class PartyMember extends Combatants
   config(PlayerCharacters) perobjectconfig dependson(BattleController) notplaceable;

var Status poison;
var Status defBuff;
var Status atkBuff;
var Status agiBuff;
var Status magBuff;
var Status accBuff;
var Status mute;
var Status virus;
var Status stone;
var Status berserk;
var Status injury;
var Status fire;
var Status water;
var Status earth;
var Status wind;

var Skill skilllist[5];

var int i;

var BattleController b;
var BattleController z;

var BossPlayerController p;

var() Equipment gear[7];

var skeletalmesh skeleton;
var materialinterface mat;
var animtree tree;
var array<animset> set;


enum equip
{
     EQ_helmet,
     EQ_armor,
     EQ_weapon,
     EQ_subWeapon,
     EQ_boots,
     EQ_gloves,
     EQ_accessory
};

simulated event postBeginPlay ()
{
   super.postbeginplay();
   self.mesh = new(self) class'SkeletalMeshComponent';
   self.mesh.setskeletalmesh(skeleton);
   self.mesh.setAnimTreeTemplate(tree);
   self.mesh.animsets = set;
   self.mesh.setmaterial(0,mat);
   foreach AllActors(class 'BattleController', z)
   {
      b = z;
   }
}

function advanceTime()
{
   timer += agility;
}

function int getTime()
{
   return timer;
}

function equipNewGear(Equipment newGear)
{
   local int slot;
   slot = newGear.getType();
   if (gear[slot] != None)
   {
      maxHP -= gear[slot].getHP();
      maxMP -= gear[slot].getMP();
   }
   foreach allActors(class 'BossPlayerController', p)
   {
      p.addInventory(gear[slot]);
      gear[slot] = newGear;
      p.removeInventory(newGear);
      maxHP += gear[slot].getHP();
      maxMP += gear[slot].getMP();
   }
}

function int getHp()
{
    return hp;
}

function setHp(int newHp)
{
    hp = newHp;
}

function int getMp()
{
    return mp;
}

function setMp(int newMp)
{
    mp = newMp;
}

function pollStatus()
{
    if (stone.getdurration() >0)
    {
        GotoState ('NotTurn');
        //updateStatus (stone);
        return;
    }

    if (accBuff.getDurration() >0)
    {
        updateStatus (accBuff);
    }

    if (agiBuff.getDurration() >0)
    {
        updateStatus (agiBuff);
    }

    if (atkBuff.getDurration() >0)
    {
        updateStatus (atkBuff);
    }

    if (defBuff.getDurration() >0)
    {
        updateStatus (defBuff);
    }

    if (magBuff.getDurration() >0)
    {
        updateStatus (magBuff);
    }

    if (mute.getDurration() >0)
    {
       updateStatus (mute);
    }

    if (injury.getDurration() >0)
    {
       updateStatus (injury);
    }

    if (poison.getDurration() >0)
    {
        setHp (hp-poison.getEffect());
        updateStatus (poison);
    }

    if (berserk.getdurration() >0)
    {
        attackEnemy (rand(6)+1);
        updateStatus (berserk);
    }

    if (fire.getdurration() >0)
    {
        updateStatus (fire);
    }

    if (water.getdurration() >0)
    {
        updateStatus (water);
    }

    if (earth.getdurration() >0)
    {
        updateStatus (earth);
    }

    if (wind.getdurration() >0)
    {
        updateStatus (wind);
    }
}

function setStatus(int duration, int effect, int type)
{
    switch (type)
    {
        case ST_poison:
           if (poison.getDurration() <=0)
           {
              poison.setDurration(duration);
              poison.setEffect(effect);
           }
           break;
        case ST_def:
           if (defBuff.getDurration() <=0)
           {
              defBuff.setDurration(duration);
              defBuff.setEffect(effect);
           }
           break;
        case ST_atk:
           if (atkBuff.getDurration() <=0)
           {
              atkBuff.setDurration(duration);
              atkBuff.setEffect(effect);
           }
           break;
        case ST_agi:
           if (agiBuff.getDurration() <=0)
           {
              agiBuff.setDurration(duration);
              agiBuff.setEffect(effect);
           }
           break;
        case ST_mag:
           if (magBuff.getDurration() <=0)
           {
              magBuff.setDurration(duration);
              magBuff.setEffect(effect);
           }
           break;
        case ST_acc:
           if (accBuff.getDurration() <=0)
           {
              accBuff.setDurration(duration);
              accBuff.setEffect(effect);
           }
           break;
        case ST_mute:
           if (mute.getDurration() <=0)
           {
              mute.setDurration(duration);
              mute.setEffect(effect);
           }
           break;
        case ST_virus:
           if (virus.getDurration() <=0)
           {
              virus.setDurration(1);
              virus.setEffect(1);
           }
           break;
        case ST_stone:
           if (stone.getDurration() <=0)
           {
              stone.setDurration(1);
              stone.setEffect(1);
           }
           break;
        case ST_berserk:
           if (berserk.getDurration() <=0)
           {
              berserk.setDurration(duration);
              berserk.setEffect(1);
           }
           break;
        case ST_injury:
           if (injury.getDurration() <=0)
           {
              injury.setDurration(duration);
              injury.setEffect(1);
           }
        case ST_fireAttack:
           if (fire.getDurration() <=0)
           {
              fire.setDurration(duration);
              fire.setEffect(1);
           }
        case ST_waterAttack:
           if (water.getDurration() <=0)
           {
              water.setDurration(duration);
              water.setEffect(1);
           }
        case ST_earthAttack:
           if (earth.getDurration() <=0)
           {
              earth.setDurration(duration);
              earth.setEffect(1);
           }
        case ST_windAttack:
           if (wind.getDurration() <=0)
           {
              wind.setDurration(duration);
              wind.setEffect(1);
           }
        default:
           break;
    }
}

function updateStatus(Status currentStatus)
{
   currentStatus.decrementDurration();
}

function int getTotalVitality()
{
   local int totalVitality;
   totalVitality = vitality;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalVitality += gear[i].getVitality();
      }
   }
   return totalVitality;
}

function int getTotalAgility()
{
   local int totalAgility;
   totalAgility = agility;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalAgility += gear[i].getagility();
      }
   }
   return totalAgility;
}

function int getTotalStrength()
{
   local int totalStrength;
   totalStrength = strength;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalStrength += gear[i].getstrength();
      }
   }
   return totalStrength;
}

function int getTotalDexterity()
{
   local int totalDexterity;
   totalDexterity = dexterity;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalDexterity += gear[i].getdexterity();
      }
   }
   return totalDexterity;
}

function int getTotalLuck()
{
   local int totalLuck;
   totalLuck = luck;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalLuck += gear[i].getluck();
      }
   }
   return totalLuck;
}

function int getTotalIntelegence()
{
   local int totalIntelegence;
   totalIntelegence = intelegence;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalIntelegence += gear[i].getintelegence();
      }
   }
   return totalIntelegence;
}

function int getTotalWisdom()
{
   local int totalWisdom;
   totalWisdom = wisdom;
   for (i = EQ_helmet; i <= EQ_accessory; i++)
   {
      if (gear[i] != None)
      {
         totalWisdom += gear[i].getwisdom();
      }
   }
   return totalWisdom;
}

event onAttackTrigger (int target)
{
   attackEnemy(target);
}

function attackEnemy(int target)
{
   local int damage;
   local int hitChance;
   local int critChance;
   local bool hit;

   //play attack animation
   hitChance = rand(100);

   hit = b.calculateHit(getTotalDexterity(), accBuff.getEffect(), hitChance, target);

   if (hit)
   {
      critChance = rand (20);
      if (critChance > luck)
      {
         damage = 1.5 * (getTotalStrength() + atkBuff.getEffect() + rand(getTotalStrength()/4));
         b.doDamage(target, damage, fire.geteffect(), water.getEffect(), earth.getEffect(), wind.getEffect() );
      }
      else
      {
         damage = getTotalStrength() + atkBuff.getEffect() + rand(getTotalStrength()/4);
         b.doDamage(target, damage, fire.geteffect(), water.getEffect(), earth.getEffect(), wind.getEffect() );
      }
   }
   gotoState ('notTurn');
}

function useItem (BossItem item, int target)
{
   foreach AllActors(class 'bossplayercontroller', p)
   {

      if (p.inventory.find(item) != Index_None && item.isA('Consumable'))
      {
         p.removeInventory(item);
         switch (item.getType())
         {
            case CO_potion:
               b.doDamage(target, item.getPower(),0,0,0,0);
               break;
            case CO_ether:
               b.changeMP(target, item.getPower());
               break;
            case CO_antidote:
               b.setstatus(target, ST_poison, 0, 0);
               break;
            case CO_vacine:
               b.setstatus(target, ST_virus, 0, 0);
               break;
            case CO_bandage:
               b.setstatus(target, ST_injury, 0, 0);
               break;
            case CO_tranq:
               b.setstatus(target, ST_berserk, 0, 0);
               break;
            case CO_antimute:
               b.setstatus(target, ST_mute, 0, 0);
               break;
            default:
               break;
         }
      }
   }
}

function useSkill (int target, int skill)
{
   local int damage;
   local int hitChance;
   local int critChance;
   local bool hit;

   //play attack animation
   hitChance = rand(100);

   hit = b.calculateHit(getTotalDexterity(), accBuff.getEffect(), hitChance, target);
   hitchance = rand(skilllist[skill].getAccuracy());

   for (i=0; i<skilllist[skill].getHitNumber(); i++)
   {

      if (hit && (hitchance == 0))
      {
         critChance = rand (20);
         if ( (critChance > luck) || skilllist[skill].getCrit() )
         {
            damage = 1.5 * (getTotalStrength() + atkBuff.getEffect() + rand(getTotalStrength()/4)) * skilllist[skill].getDamage();
            b.doDamage(target, damage, skilllist[skill].getFire(), skilllist[skill].getWater(), skilllist[skill].getEarth(), skilllist[skill].getWind() );
         }
         else
         {
            damage = (getTotalStrength() + atkBuff.getEffect() + rand(getTotalStrength()/4)) * skilllist[skill].getDamage();
            b.doDamage(target, damage, skilllist[skill].getFire(), skilllist[skill].getWater(), skilllist[skill].getEarth(), skilllist[skill].getWind() );
         }

         if (skilllist[skill].getStatus() != ST_none)
         {
            b.setStatus(target, skilllist[skill].getStatus(), skilllist[skill].getdurration(), skilllist[skill].getEffect());
         }
      }
   }
   gotoState ('notTurn');
}

function getHurt (int damage, int fireElement, int waterElement, int earthElement, int windElement)
{
   local int defence;
   defence = (getTotalVitality() + defBuff.getEffect() / 2);
   //elemental equations go here
   setHP(getHP() - (damage - defence));
}

function startTurn()
{
}

state notTurn
{
   function startTurn ()
   {
      gotoState ('turn');
   }

Begin:
   //play idle animation
}

state turn
{

Begin:
   pollStatus();
   //displaymenu
}

state dead
{
}


defaultproperties
{
   name = "partymember";

   //mat = materialinterface'anim_lab.animations.brick';
   begin object Class=SkeletalMeshComponent name=MySkeletalMesh
      SkeletalMexh = SkeletalMesh'Anim_LaB.animations.Blob';
      AnimSet[0] = AnimSet'Anim_LaB.animations.jiggle';
      AnimTreeTemplate = AnimTree'Anim_LaB.animations.test_Blob';
      bownernosee = false;
   end object

   mesh = MySkeletalMesh;
   component.add(MySkeletalMesh);
}
